import { u64, i64, toU64, toI64, MachineMode, Registers as RegisterEnum } from '../types';
import { RegisterManager } from '../cpu/Registers';
import { MemoryManager } from '../memory/MemoryManager';
import { InstructionDecoder } from '../decoder/InstructionDecoder';
import { InstructionExecutor } from '../executor/InstructionExecutor';
import { SystemCallHandler } from '../syscall/SystemCallHandler';
import { ElfLoader } from '../elf/ElfLoader';

// 虚拟机运行状态
enum MachineStatus {
  RUNNING,
  PAUSED,
  STOPPED,
  ERROR
}

export class Machine {
  private mode: MachineMode;
  private status: MachineStatus;
  private registerManager: RegisterManager;
  private memoryManager: MemoryManager;
  private instructionDecoder: InstructionDecoder;
  private instructionExecutor: InstructionExecutor;
  private systemCallHandler: SystemCallHandler;
  private elfLoader: ElfLoader;
  private cycles: number;
  private maxCycles: number;
  private errorMessage: string | null;

  constructor(mode: MachineMode = MachineMode.LONG) {
    this.mode = mode;
    this.status = MachineStatus.STOPPED;
    this.cycles = 0;
    this.maxCycles = 1000000; // 默认最大周期数
    this.errorMessage = null;

    // 初始化各个组件
    this.memoryManager = new MemoryManager();
    this.registerManager = new RegisterManager();
    this.instructionDecoder = new InstructionDecoder(this.memoryManager);
    this.instructionExecutor = new InstructionExecutor(
      this.registerManager,
      this.memoryManager,
      this.instructionDecoder,
      this.mode
    );
    this.systemCallHandler = new SystemCallHandler(
      this.registerManager,
      this.memoryManager
    );
    this.elfLoader = new ElfLoader(this.memoryManager, this.registerManager);
  }

  // 初始化虚拟机
  initialize(): void {
    // 重置所有组件
    this.registerManager.reset();
    
    // 根据模式设置初始状态
    switch (this.mode) {
      case MachineMode.LONG:
        this.initializeLongMode();
        break;
      case MachineMode.LEGACY:
        this.initializeLegacyMode();
        break;
      case MachineMode.REAL:
        this.initializeRealMode();
        break;
    }

    // 设置默认内存映射
    this.mapDefaultMemory();

    this.status = MachineStatus.PAUSED;
    this.cycles = 0;
    this.errorMessage = null;
  }

  // 初始化长模式（64位）
  private initializeLongMode(): void {
    // 设置初始栈指针
    const stackAddr = toU64(0x7ffffff00000);
    this.registerManager.setStackPointer(stackAddr);
    this.registerManager.setFramePointer(stackAddr);
    
    // 映射栈内存
    this.memoryManager.map(stackAddr, 0x10000); // 64KB栈空间
  }

  // 初始化传统模式（32位保护模式）
  private initializeLegacyMode(): void {
    // 设置初始栈指针
    const stackAddr = toU64(0xffffff00);
    this.registerManager.setStackPointer(stackAddr);
    this.registerManager.setFramePointer(stackAddr);
    
    // 映射栈内存
    this.memoryManager.map(stackAddr, 0x1000); // 4KB栈空间
  }

  // 初始化实模式（16位）
  private initializeRealMode(): void {
    // 设置初始栈指针
    const stackAddr = toU64(0xffff);
    this.registerManager.setStackPointer(stackAddr);
    
    // 映射低内存
    this.memoryManager.map(toU64(0), 0x100000); // 1MB内存空间
  }

  // 映射默认内存区域
  private mapDefaultMemory(): void {
    // 映射程序代码区域
    const codeAddr = toU64(0x400000); // ELF程序的默认加载地址
    this.memoryManager.map(codeAddr, 0x1000000); // 16MB代码空间
    
    // 设置初始指令指针
    this.registerManager.setInstructionPointer(codeAddr);
  }

  // 加载程序（支持ELF和普通二进制文件）
  loadProgram(data: Uint8Array, programName: string = 'program'): void {
    // 尝试作为ELF文件加载
    if (this.elfLoader.isSupportedExecutable(Array.from(data))) {
      console.log(`Loading ELF file: ${programName}`);
      const success = this.elfLoader.loadElf(Array.from(data), programName);
      if (success) {
        return;
      }
    }

    // 作为普通二进制文件加载
    console.log(`Loading flat binary: ${programName}`);
    const defaultAddress = toU64(0x400000);
    
    // 确保目标地址有内存映射
    if (!this.memoryManager.isValidAddress(defaultAddress, data.length)) {
      this.memoryManager.map(defaultAddress, data.length);
    }
    
    // 写入程序数据
    this.memoryManager.write(defaultAddress, data);
    
    // 设置指令指针指向程序入口
    this.registerManager.setInstructionPointer(defaultAddress);
  }

  // 加载ELF文件
  loadElfFile(data: Uint8Array, programName: string = 'program'): boolean {
    return this.elfLoader.loadElf(Array.from(data), programName);
  }

  // 加载Flat二进制文件
  loadFlatBinary(data: Uint8Array, baseAddress: u64 = toU64(0x400000)): boolean {
    return this.elfLoader.loadFlatBinary(Array.from(data), baseAddress);
  }

  // 运行虚拟机
  run(): MachineStatus {
    this.status = MachineStatus.RUNNING;
    
    try {
      while (this.status === MachineStatus.RUNNING && this.cycles < this.maxCycles) {
        this.step();
      }
    } catch (error) {
      this.status = MachineStatus.ERROR;
      this.errorMessage = error instanceof Error ? error.message : String(error);
      console.error('Machine error:', this.errorMessage);
    }
    
    return this.status;
  }

  // 单步执行
  step(): void {
    if (this.status !== MachineStatus.RUNNING && this.status !== MachineStatus.PAUSED) {
      throw new Error(`Cannot step when machine is ${MachineStatus[this.status]}`);
    }

    this.status = MachineStatus.RUNNING;
    
    try {
      // 获取当前指令指针
      const ip = this.registerManager.getInstructionPointer();
      
      // 解码指令
      const instruction = this.instructionDecoder.decodeInstruction(ip);
      
      // 检查是否是系统调用指令（SYSCALL）
      if (instruction.opcode === 0x0f && this.memoryManager.read(toU64(Number(ip) + 1), 1)[0] === 0x05) {
        // 处理系统调用
        const syscallNumber = this.registerManager.getRegister(RegisterEnum.RAX);
        this.systemCallHandler.handleSyscall(Number(syscallNumber));
        
        // 前进指令指针
        this.registerManager.setInstructionPointer(toU64(Number(ip) + 2));
        
        // 增加周期计数并返回，避免执行下面的代码
        this.cycles++;
        return;
      } else {
        // 执行指令
        this.instructionExecutor.executeInstruction(instruction);
        
        // 如果指令没有修改指令指针（如跳转指令），则前进到下一条指令
        if (this.registerManager.getInstructionPointer() === ip) {
          this.registerManager.setInstructionPointer(toU64(Number(ip) + instruction.size));
        }
      }
      
      // 增加周期计数
      this.cycles++;
    } catch (error) {
      this.status = MachineStatus.ERROR;
      this.errorMessage = error instanceof Error ? error.message : String(error);
      throw error;
    }
  }

  // 暂停虚拟机
  pause(): void {
    if (this.status === MachineStatus.RUNNING) {
      this.status = MachineStatus.PAUSED;
    }
  }

  // 停止虚拟机
  stop(): void {
    this.status = MachineStatus.STOPPED;
  }

  // 设置最大周期数
  setMaxCycles(maxCycles: number): void {
    this.maxCycles = maxCycles;
  }

  // 获取虚拟机状态
  getStatus(): MachineStatus {
    return this.status;
  }

  // 获取错误信息
  getErrorMessage(): string | null {
    return this.errorMessage;
  }

  // 获取周期计数
  getCycles(): number {
    return this.cycles;
  }

  // 获取寄存器管理器
  getRegisterManager(): RegisterManager {
    return this.registerManager;
  }

  // 获取内存管理器
  getMemoryManager(): MemoryManager {
    return this.memoryManager;
  }

  // 打印虚拟机状态（调试用）
  printState(): void {
    console.log('Machine State:');
    console.log(`  Mode: ${MachineMode[this.mode]}`);
    console.log(`  Status: ${MachineStatus[this.status]}`);
    console.log(`  Cycles: ${this.cycles}`);
    
    if (this.errorMessage) {
      console.log(`  Error: ${this.errorMessage}`);
    }
    
    // 打印寄存器状态
    this.registerManager.printState();
    
    // 打印内存使用统计
    const memoryStats = this.memoryManager.getMemoryStats();
    console.log('Memory Stats:');
    console.log(`  Total Pages: ${memoryStats.totalPages}`);
    console.log(`  Used Pages: ${memoryStats.usedPages}`);
    console.log(`  Memory Regions: ${memoryStats.memoryRegions}`);
  }
}